#include "stdafx.h"
#include "Particle.h"
#include "Texture.h"


float	slowdown=2.0f;				// Slow Down Particles
float	xspeed;						// Base X Speed (To Allow Keyboard Direction Of Tail)
float	yspeed;						// Base Y Speed (To Allow Keyboard Direction Of Tail)
float	zoom=-40.0f;				// Used To Zoom Out

GLuint	col;						// Current Color Selection
GLuint	delay;						// Rainbow Effect Delay


#define NUM_PARTICLE_HOLDERS		5

ParticleHolder holders[NUM_PARTICLE_HOLDERS];

static GLuint particleTexture;

static GLfloat colors[12][3]=		// Rainbow Of Colors
{
	{1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f},
	{0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f},
	{0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f}
};

static int LoadGLTextures()									// Load Bitmap And Convert To A Texture
{
    int Status=FALSE;								// Status Indicator
    TextureImage *texImage = new TextureImage();

	LoadTexBmp(texImage, "Data/Particle.bmp");
    //if (texImage=LoadBMP("Data/Particle.bmp"))	// Load Particle Texture
    {
		Status=TRUE;								// Set The Status To TRUE
		glGenTextures(1, &particleTexture);				// Create One Texture

		glBindTexture(GL_TEXTURE_2D, particleTexture);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texImage->width, texImage->height, 0, GL_RGB, GL_UNSIGNED_BYTE, texImage->imageData);
    }

    if (texImage)							// If Texture Exists
	{
		if (texImage->imageData)					// If Texture Image Exists
		{
			free(texImage->imageData);			// Free The Texture Image Memory
		}
		delete texImage;						// Free The Image Structure
	}
    return Status;									// Return The Status
}



void ParticleHolder::Init()
{
	GLuint	loop;						// Misc Loop Variable
	for (loop = 0; loop < numParticles; loop++)				// Initials All The Textures
	{
		particle[loop].active=true;								// Make All The Particles Active
		particle[loop].life=1.0f;								// Give All The Particles Full Life
		particle[loop].fade=float(rand()%100)/1000.0f+0.003f;	// Random Fade Speed
		particle[loop].x=initX;						// Center On X Axis
		particle[loop].y=initY;						// Center On Y Axis
		particle[loop].z=0.0f;						// Center On Z Axis
		particle[loop].r=colors[loop*(12/MAX_PARTICLES)][0];	// Select Red Rainbow Color
		particle[loop].g=colors[loop*(12/MAX_PARTICLES)][1];	// Select Red Rainbow Color
		particle[loop].b=colors[loop*(12/MAX_PARTICLES)][2];	// Select Red Rainbow Color
		particle[loop].xi=float((rand()%50)-26.0f)*10.0f;		// Random Speed On X Axis
		particle[loop].yi=float((rand()%50)-25.0f)*10.0f;		// Random Speed On Y Axis
		particle[loop].zi=float((rand()%50)-25.0f)*10.0f;		// Random Speed On Z Axis
		particle[loop].xg=0.0f;									// Set Horizontal Pull To Zero
		particle[loop].yg=-0.8f;								// Set Vertical Pull Downward
		particle[loop].zg=0.0f;									// Set Pull On Z Axis To Zero
	}

}

void ParticleHolder::Draw()
{
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE);

	glDisable(GL_DEPTH_TEST);
	
	glBindTexture(GL_TEXTURE_2D, particleTexture);			// Select Our Texture

	bool hasActive = false;
	for (int loop=0;loop<numParticles;loop++)					// Loop Through All The Particles
	{
		if (particle[loop].active)							// If The Particle Is Active
		{
			hasActive = true;

			float x=particle[loop].x;						// Grab Our Particle X Position
			float y=particle[loop].y;						// Grab Our Particle Y Position
			float z=particle[loop].z+zoom;					// Particle Z Pos + Zoom

			// Draw The Particle Using Our RGB Values, Fade The Particle Based On It's Life
			glColor4f(particle[loop].r,particle[loop].g,particle[loop].b,particle[loop].life);

			glBegin(GL_TRIANGLE_STRIP);						// Build Quad From A Triangle Strip
			    glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z); // Top Right
				glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z); // Top Left
				glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z); // Bottom Right
				glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z); // Bottom Left
			glEnd();										// Done Building Triangle Strip

			particle[loop].x+=particle[loop].xi/(slowdown*1000);// Move On The X Axis By X Speed
			particle[loop].y+=particle[loop].yi/(slowdown*1000);// Move On The Y Axis By Y Speed
			particle[loop].z+=particle[loop].zi/(slowdown*1000);// Move On The Z Axis By Z Speed

			particle[loop].xi+=particle[loop].xg;			// Take Pull On X Axis Into Account
			particle[loop].yi+=particle[loop].yg;			// Take Pull On Y Axis Into Account
			particle[loop].zi+=particle[loop].zg;			// Take Pull On Z Axis Into Account
			particle[loop].life-=particle[loop].fade;		// Reduce Particles Life By 'Fade'

			if (particle[loop].life<0.0f)					// If Particle Is Burned Out
			{
				particle[loop].active = false;
			}
		}
    }

	if (hasActive == false) {
		available = true;
	}

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glEnable(GL_DEPTH_TEST);
}


void InitializeParticleSystem()
{
	LoadGLTextures();
	
	for (int i = 0; i < NUM_PARTICLE_HOLDERS; ++i)
	{
		holders[i].available = true;
	}
}

void FinalizeParticleSystem()
{
	glDeleteTextures(1, &particleTexture);
}

void Log(const char* format,...)
{
	char buffer[4096];
	va_list vaList;
	va_start(vaList, format);
	_vsnprintf(buffer, 4096, format, vaList);
	va_end(vaList);
	OutputDebugString(buffer);
}

void AllocParticleHolder(float x, float y, float dist)
{
	Log("%f %f\n", x, y, dist);
	for (int i = 0; i < NUM_PARTICLE_HOLDERS; ++i)
	{
		if (holders[i].available == true)
		{
			holders[i].available = false;
			holders[i].numParticles = MAX_PARTICLES / fabsf(dist);
			holders[i].initX = x;
			holders[i].initY = y;
			holders[i].initZ = 0;//dist;
			holders[i].Init();
			break;
		}
	}
}

void DrawParticles()
{
	for (int i = 0; i < NUM_PARTICLE_HOLDERS; ++i) 
	{
		if (holders[i].available == false)
		{
			holders[i].Draw();
		}
	}
}